// jdbcsh - An interactive shell for JDBC databases
// Copyright (C) 2007 Dan Boitnott
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

package jdbcsh;

import java.io.PrintStream;
import java.sql.*;
import java.util.List;
import java.util.ArrayList;

/**
 *
 * @author Dan Boitnott
 */
public class ResultFormatter {
    public static void printResultSet(ResultSet res) {
        printResultSet(System.out, res);
    }
    
    public static void printResultSet(PrintStream fp, ResultSet res) {
        printTable(fp, new ResultSetTable(res));
    }
    
    public static void printTable(Table tbl) {
        printTable(System.out, tbl);
    }
    
    public static void printTable(Table tbl, boolean addRowCount) {
        printTable(System.out, tbl, addRowCount);        
    }
    
    public static void printTable(PrintStream fp, Table tbl) {
        printTable(fp, tbl, true);
    }
    
    public static void printTable(PrintStream fp, Table tbl, boolean addRowCount) {
        long count = 0;        
                
        // Calculate the column widths
        int ccount = tbl.getColumnCount();
        List<Integer> cwidths = calcColWidths(tbl);               
        
        // build header & separator lines
        String hl = "";
        String sl = "";
        for (int i = 0; i < ccount; i++) {
            int w = cwidths.get(i).intValue();
            hl += centerString(tbl.getColumnLabel(i), w);
            sl += repeatString("-", w);
            if (i < (ccount - 1)) {
                hl += " | ";
                sl += "-+-";
            }
        }
        fp.println(hl);
        fp.println(sl);        
        
        while (tbl.next()) {
            count++;     
            
            // Step through columns
            for (int i = 0; i < ccount; i++) {
                // Blank out null values
                String v = tbl.getString(i);
                if (v == null) v = "";
                
                // output the column value
                fp.print(String.format("%-" + cwidths.get(i).intValue() + "s", v));
                
                // Add the separator
                if (i < (ccount - 1)) fp.print(" | ");
            }
            fp.println("");
        }
        
        if (addRowCount) {
            fp.println("");
            fp.println(count + " rows)");
        }
    }
    
    public static List calcColWidths(Table tbl) {
        ArrayList<Integer> ret = new ArrayList<Integer>();
        
        int q = tbl.getColumnCount();
        for (int i = 0; i < q; i++) {
            ret.add(new Integer(Math.max(tbl.getColumnDisplaySize(i), tbl.getColumnLabel(i).length())));
        }
        
        return ret;
    }
    
    public static String centerString(String s, int w) {
        String ret = new String(s);
        
        if (ret.length() >= w) return ret;
        
        ret = repeatString(" ", (w - ret.length()) / 2) + ret;
        ret += repeatString(" ", (w - ret.length()));
        
        return ret;
    }   
    
    public static String repeatString(String s, int c) {        
        String ret = "";
        for (int i = 0; i < c; i++) ret += s;
        return ret;
    }
}
